﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once
#include "OwnerPtr.h"
#include "Box3d.h"
#include "Coordinate3d.h"
#include "Box2d.h"
#include "Vector3d.h"
#include "GcmpGeometryInterface.h"
#include "CurvesPositionTypes.h"
#include "LoopAxisPositionTypes.h"
#include "BoxGeometryPositionTypes.h"
#include "PointBodyPositionTypes.h"
#include "BodiesPositionTypes.h"
#include "PointPolygonPositionTypes.h"
#include "CurveBodyPositionTypes.h"
#include "Curve2dPolygonPositionTypes.h"
#include "LoopsPositionTypes.h"
#include "PolygonsPositionTypes.h"
#include "WeakReferenceable.h"


namespace gcmp
{
    class IPolygon;
    class ILine2d;
    class ICurve2d;
    class ILine3d;
    class ICurve3d;
    class ILoop;
    class IBody;
    class IPolyCurve;

    /// \brief 位置关系判断类，用于判断几何对象间的位置关系
    class IPositionJudge : public WeakReferenceable
    {
    public:
        virtual ~IPositionJudge() {}

        /// \brief  判断两条二维曲线的位置关系 （1、退化为点的重合段认为是相交； 2、有重合有相交认为是重合）
        /// \param const ICurve2d *pFirGmICurve2d  第一条二维曲线
        /// \param const ICurve2d *pSecGmICurve2d  第二条二维曲线
        /// \return    曲线和曲线的位置关系
        virtual CurvesPositionTypes GetPosition(const ICurve2d *pFirGmICurve2d, const ICurve2d *pSecGmICurve2d, double dDistEpsilon) const = 0;

        /// \brief  判断两条三维曲线的位置关系 （1、退化为点的重合段认为是相交； 2、有重合有相交认为是重合）
        /// \param const ICurve3d *pFirGmICurve3d  第一条三维曲线
        /// \param const ICurve3d *pSecGmICurve3d  第二条三维曲线
        /// \return    曲线和曲线的位置关系
        virtual CurvesPositionTypes GetPosition(const ICurve3d *pFirGmICurve3d, const ICurve3d *pSecGmICurve3d, double dDistEpsilon) const = 0;

        /// \brief 判断封闭多段线和轴线的位置关系
        /// \param const IPolyCurve *pClosedPolyCurvep              环
        /// \param const ILine2d *pAxis2d            轴线（参数范围任意）
        /// \return  LoopLinePositionType                位置关系类型
        virtual LoopAxisPositionTypes GetPosition(const IPolyCurve *pClosedPolyCurve, const ILine2d *pAxis2d) const = 0;

        /// \brief 判断二维线和多边形的位置关系
        /// \param const ICurve2d *pGmICurve2d         二维线
        /// \param const IPolygon* pGmPolygon           多边形
        /// \return  Curve2dPolygonPositionType              位置关系类型
        virtual Curve2dPolygonPositionTypes GetPosition(const ICurve2d *pGmICurve2d, const IPolygon* pGmPolygon, double dDistEpsilon) const = 0;

        /// \brief 判断二维包围盒和二维曲线的位置关系
        /// \param const Box2d &rect                     二维包围盒
        /// \param const ICurve2d *pGmICurve2d         二维曲线
        /// \return  BoxGeometryPositionTypes                         位置关系类型
        virtual BoxGeometryPositionTypes GetPosition(const Box2d &rect, const ICurve2d *pGmICurve2d, double dDistEpsilon) const = 0;

        /// \brief 判断二维包围盒和多边形的位置关系 BoxGeometryPositionTypes
        /// \param const Box2d &rect                二维包围盒
        /// \param const IPolygon *pGmPolygon       多边形
        /// \return  BoxGeometryPositionTypes       位置关系类型
        virtual BoxGeometryPositionTypes GetPosition(const Box2d &rect, const IPolygon *pGmPolygon, double dDistEpsilon) const = 0;

        /// \brief 判断二维包围盒和多边形的位置关系 PolygonsPositionTypes
        /// \param const Box2d &rect                二维包围盒
        /// \param const IPolygon *pGmPolygon       多边形
        /// \return  PolygonsPositionTypes          位置关系类型
        virtual PolygonsPositionTypes GetOriginPosition(const Box2d &rect, const IPolygon *pGmPolygon, double dDistEpsilon) const = 0;

        /// \brief 判断二维包围盒和二维多段线的位置关系 BoxGeometryPositionTypes
        /// \param const Box2d &rect                二维包围盒
        /// \param const IPolyCurve *pGmPolyCurve   二维多段线
        /// \return  BoxGeometryPositionTypes       位置关系类型
        virtual BoxGeometryPositionTypes GetPosition(const Box2d &rect, const IPolyCurve *pGmPolyCurve, double dDistEpsilon) const = 0;


        /// \brief 判断点和体的位置关系
        /// \param const Vector3d& point,          点
        /// \param const IBody *pGmIBody         体
        /// \return  ValuePosition                     位置关系类型
        virtual PointBodyPositionTypes GetPosition(const Vector3d& point, const IBody *pGmIBody) const = 0;

        /// \brief 判断两个体的位置关系
        /// \param const IBody* pFirGmIBody      第一个体
        /// \param const IBody* pGmISecBody      第二个体
        /// \param dDistanceEpsilon    距离容差
        /// \return  两个体的内外关系
        virtual BodiesPositionTypes GetPosition(const IBody* pFirGmIBody, const IBody* pGmISecBody, double dDistanceEpsilon) const = 0;

        /// \brief 判断环和环的位置关系
        /// \param const ILoop *pFirGmLoop         第一个环
        /// \param const ILoop *pSecGmLoop         第二个环
        /// \return  LoopsPositionTypes                 位置关系类型
        virtual LoopsPositionTypes GetPosition(const IPolyCurve *pFirGmLoop, const IPolyCurve *pSecGmLoop) const = 0;

        /// \brief 判断多边形和多边形的位置关系
        /// \param const IPolygon *pFirGmPolygon         第一个多边形
        /// \param const IPolygon *pSecGmPolygon         第二个多边形
        /// \return  PolygonsPositionTypes                    位置关系类型
        virtual PolygonsPositionTypes GetPosition(const IPolygon *pFirGmPolygon, const IPolygon *pSecGmPolygon, double dDistEpsilon) const = 0;

        /// \brief 判断点和多边形的位置关系
        /// \param const Vector2d &point        点
        /// \param const IPolygon* pPolygon    多边形
        /// \param double dDistEpsilon          点在多边形上的距离容差
        /// \return  点在多边形的内外关系
        virtual PointPolygonPositionTypes GetPosition(const Vector2d &point, const IPolygon* pPolygon, double dDistEpsilon) const = 0;

        /// \brief 判断三维曲线和体的位置关系
        /// \param const ICurve3d &pGmICurve3d        三维曲线
        /// \param const IBody* pIBody                体
        /// \param double dDistEpsilon                  距离容差
        /// \return  判断三维曲线和体的位置关系
        virtual CurveBodyPositionTypes GetPosition(const ICurve3d* pGmICurve3d, const IBody* pIBody, double dDistEpsilon) const = 0;

        /// \brief  判断两条直线是否平行
        /// \param      pFirLine3d          第一条直线
        /// \param      pSecLine3d          第二条直线
       /// \return         bool                若平行，返回true；否则返回false
        virtual bool IsParallel(const ILine3d* pFirLine3d, const ILine3d* pSecLine3d) const = 0;

        /// \brief  检测数据是否在容差内对齐:顶点对齐到顶点，点对齐到曲线上
        ///
        /// 点与点的距离或者点到线的距离在[distEpsilon/disturbCoef, distEpsilon*disturbCoef]范围内认为没有对齐
        /// \param curves             二维曲线
        /// \param[in,out] toAlignedPts   曲线和没有对齐到该曲线上的点。输入为空数组
        /// \param[in] distEpsilon        距离容差
        /// \param[in] disturbCoef        扰动系数>1.0
        /// \return  成功返回true；否则返回false
        virtual bool GetUnalignedPoints(const std::vector<const ICurve2d*> &curves, std::map<const ICurve2d*, std::vector<Vector2d>> &toAlignedPts, double distEpsilon, double disturbCoef) const = 0;
    };
}
